package cc.z8g.browser.dialog

import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.EditText
import android.widget.ListView
import android.widget.TextView
import androidx.annotation.StringRes
import cc.z8g.browser.R
import cc.z8g.browser.utils.MiscUtils

object BrowserDialog {

    @JvmStatic
    fun show(activity: Activity, @StringRes title: Int, vararg items: DialogItem) = show(activity, activity.getString(title), *items)

    @JvmStatic
    fun show(activity: Activity, title: String?, vararg items: DialogItem) {
        val builder = AlertDialog.Builder(activity)
        val layout = LayoutInflater.from(activity).inflate(R.layout.list_dialog, null)
        val titleView = layout.findViewById<TextView>(R.id.dialog_title)
        val listView = layout.findViewById<ListView>(R.id.dialog_list)
        val itemList = items.filter(DialogItem::isConditionMet)

        if (title?.isNotEmpty() == true) {
            titleView.text = title
        }
        builder.setView(layout)
        val dialog = builder.resizeAndShow()
        val dialogItemAdapter = DialogItemAdapter(activity, R.id.title_text, itemList)
        listView.adapter = dialogItemAdapter
        listView.setOnItemClickListener { parent, view, position, id ->
            val item = items.get(position)
            item.onClick()
            dialog.dismiss()
        }
    }

    @JvmStatic
    fun showPositiveNegativeDialog(
        activity: Activity,
        @StringRes title: Int,
        @StringRes message: Int,
        messageArguments: Array<Any>? = null,
        positiveButton: DialogItem,
        negativeButton: DialogItem,
        onCancel: Runnable?
    ) {
        val messageValue = if (messageArguments != null) {
            activity.getString(message, *messageArguments)
        } else {
            activity.getString(message)
        }
        AlertDialog.Builder(activity).apply {
            setTitle(title)
            setMessage(messageValue)
            onCancel?.let { setOnCancelListener { onCancel.run() } }
            setPositiveButton(positiveButton.title) { _, _ -> positiveButton.onClick() }
            setNegativeButton(negativeButton.title) { _, _ -> negativeButton.onClick() }
        }.resizeAndShow()
    }

    @JvmStatic
    fun showEditText(
        activity: Activity,
        @StringRes title: Int,
        @StringRes hint: Int,
        @StringRes action: Int,
        textInputListener: (String) -> Unit
    ) = showEditText(activity, title, hint, null, action, textInputListener)

    @JvmStatic
    fun showEditText(
        activity: Activity,
        @StringRes title: Int,
        @StringRes hint: Int,
        currentText: String?,
        @StringRes action: Int,
        textInputListener: (String) -> Unit
    ) {
        val dialogView = LayoutInflater.from(activity).inflate(R.layout.dialog_edit_text, null)
        val editText = dialogView.findViewById<EditText>(R.id.dialog_edit_text)

        editText.setHint(hint)
        if (currentText != null) {
            editText.setText(currentText)
        }

        AlertDialog.Builder(activity)
            .setTitle(title)
            .setView(dialogView)
            .setPositiveButton(action) { _, _ -> textInputListener(editText.text.toString()) }
            .resizeAndShow()
    }

    @JvmStatic
    fun showEditText(
        activity: Activity,
        title: String,
        hint: String?,
        currentText: String?,
        @StringRes action: Int,
        textInputListener: (String) -> Unit,
    ) {
        val dialogView = LayoutInflater.from(activity).inflate(R.layout.dialog_edit_text, null)
        val editText = dialogView.findViewById<EditText>(R.id.dialog_edit_text)

        editText.setHint(hint)
        if (currentText != null) {
            editText.setText(currentText)
        }

        AlertDialog.Builder(activity)
            .setTitle(title)
            .setView(dialogView)
            .setPositiveButton(action) { _, _ -> textInputListener(editText.text.toString()) }
            .setCancelable(true)
            .resizeAndShow()
    }

    @JvmStatic
    fun setDialogSize(activity: Context, dialog: Dialog) {
        val res = activity.resources
        var maxWidth = res.getDimensionPixelSize(R.dimen.dialog_max_size)
        val padding = res.getDimensionPixelSize(R.dimen.dialog_padding)
        val screenSize = MiscUtils.getScreenWidth(activity)
        if (maxWidth > screenSize - 2 * padding) {
            maxWidth = screenSize - 2 * padding
        }
        dialog.window?.setLayout(maxWidth, ViewGroup.LayoutParams.WRAP_CONTENT)
    }

    @Suppress("NOTHING_TO_INLINE")
    inline fun AlertDialog.Builder.resizeAndShow(): Dialog = show().also { setDialogSize(context, it) }

}
